<script setup lang="ts">
import type { FormConfigModel, FormConfigElement } from '../shared'
import { NConfigProvider, NDrawer, useDialog } from 'naive-ui'
import themeOverrides from './themeOverrides'
import sharedForm from '../sharedForm'
import { ref } from 'vue'

import DynamicFormConfigHandles from '../components/DynamicFormConfigHandles.vue'
import FormConfigJsonEditor from './FormConfigJsonEditor.vue'
import FormJsonPreview from './FormJsonPreview.vue'
import FormConfigs from './FormConfigs.vue'
import FormControl from './FormControl.vue'
import FormPreview from './FormPreview.vue'

const dialog = useDialog()

const model = ref<FormConfigModel[]>([])

const jsonEditorVisible = ref(false)
const jsonEditorValue = ref<FormConfigModel | FormConfigElement | null>(null)
const handleUpdateJsonEditorVisible = (v: boolean) => {
  jsonEditorVisible.value = v
  if (!v) jsonEditorValue.value = null
}
const handleUpdateJsonEditorValue = (v: FormConfigModel | FormConfigElement | null) => {
  Reflect.ownKeys(v!).forEach((key) => {
    // @ts-ignore
    Reflect.set(jsonEditorValue.value, key, Reflect.get(v!, key))
  })
}

const formConfigsInst = ref<{ addFile: Function; updateFile: Function } | null>(null)
const activeJsonName = ref<string | null>(null)

const handleAddGroup = (title: string | null) => {
  model.value.push({
    id: sharedForm.getUid(),
    title,
    elements: []
  })
}

const settingGroup = (value: FormConfigModel) => {
  jsonEditorValue.value = value
  jsonEditorVisible.value = true
}
const settingItem = (value: FormConfigElement) => {
  jsonEditorValue.value = value
  jsonEditorVisible.value = true
}
const deleteGroup = (parent: FormConfigModel[], i: number) => {
  dialog.warning({
    title: '确定删除分组？',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick() {
      parent.splice(i, 1)
    }
  })
}
const deleteItem = (parent: FormConfigElement[], i: number) => {
  dialog.warning({
    title: '确定删除元素？',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick() {
      parent.splice(i, 1)
    }
  })
}
</script>

<template>
  <NConfigProvider
    abstract
    :theme-overrides="themeOverrides"
  >
    <div class="dynamic-form-config">
      <FormConfigs
        ref="formConfigsInst"
        v-model:active="activeJsonName"
        v-model:json="model"
      />
      <FormControl />
      <FormPreview
        :value="model"
        @setting:group="settingGroup"
        @setting:item="settingItem"
        @delete:group="deleteGroup"
        @delete:item="deleteItem"
      />
      <FormJsonPreview :value="model" />
    </div>

    <DynamicFormConfigHandles
      :show-update-file="!!activeJsonName"
      @add:group="handleAddGroup"
      @add:file="formConfigsInst?.addFile($event)"
      @update:file="formConfigsInst?.updateFile(activeJsonName!, model)"
    />

    <NDrawer
      :show="jsonEditorVisible"
      @update:show="handleUpdateJsonEditorVisible"
      :default-width="520"
      placement="left"
      resizable
    >
      <FormConfigJsonEditor
        :value="jsonEditorValue"
        @update:value="handleUpdateJsonEditorValue"
      />
    </NDrawer>
  </NConfigProvider>
</template>

<style>
body {
  --primary-color: #36ad6a;
  --border-color: #6c5ce7;
  --group-bg-color: #abdec326;
  --primary-bg-color: #3c40c6;
}
</style>

<style scoped>
.dynamic-form-config {
  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: calc(65vh - 30px) 35vh;
  grid-template-areas:
    'form-configs form-control form-preview'
    'form-configs form-control form-json-preview';
  gap: 10px;
  height: 100vh;
  padding: 10px;
  color: #ffffff;
  background: url('@/DynamicForm/src/assets/background.svg'), #3c40c6;
}

.dynamic-form-config > div {
  border: 1px solid var(--border-color);
}

.form-configs {
  grid-area: form-configs;
}

.form-control {
  grid-area: form-control;
}

.form-preview {
  grid-area: form-preview;
}

.form-json-preview {
  grid-area: form-json-preview;
}
</style>
